// ChessXMLParser.h
//
// Created By: Jeremy Butler
// Created On: 23-Mar-2011
//
// An chess XML Parser that parses the file into the pieces and history of the saved game.

#ifndef XML_PARSE_H
#define XML_PARSE_H

#include "Piece.h"
#include "Move.h"

#include <stack>
#include <vector>
using namespace std;

class ChessXMLParser {
private:
  vector<pair<Piece *, Location> > pieces;
  deque<Move> history;

public:
  //! @brief No-Arg Constructor
  ChessXMLParser();

  //! @brief Copy Constructor
  //! @param other The ChessXMLParser to copy.
  ChessXMLParser(const ChessXMLParser & other);

  //! @brief Operator = used for copying another ChessXMLParser to this one.
  //! @param other The ChessXMLParser to be copied into this one.
  //! @return a reference to the newly copied ChessXMLParser.
  ChessXMLParser & operator = (const ChessXMLParser & other);

  //! @brief Destructor
  ~ChessXMLParser();

  //! @brief Get the pieces that were parsed from the chess XML file.
  //! @return A set of Pieces parsed from the chess XML file
  const vector<pair<Piece *, Location> > & GetPieces() const;

  //! @brief Get the Move History that was parsed from the chess XML file.
  //! @return a stack of the Moves that was parsed from the chess XML file.
  const deque<Move> & GetHistory() const;

  //! @brief Parse the chess XML file
  //! @param fileName the path of the XML file to parse.
  //! @throw FileException when there is an error parsing the file.
  void Parse(const string & fileName);

  //! @brief Method for testing
  //! @param os a reference to the output stream where to print results.
  //! @return true if tests succeeded. False otherwise.
  static bool Test(ostream & os);

private:
  void ParseXML(const string & xmlText);
  pair<Piece *, Location> ParsePiece(const string & attributes);
  void ParseBoard(string::const_iterator start, string::const_iterator end);
  void ParseHistory(string::const_iterator start, string::const_iterator end);
  Move ParseMove(string::const_iterator start, string::const_iterator end);
  string LoadFile(const string & fileName) const;
  void Clear();
  
};

#endif /* XML_PARSE_H */
